package luzhin;

import java.util.*;
import java.io.*;

/**
 * Class for testing weather the game is over. 
 * @author lacungus
 *
 */
public class MateValidator implements Serializable {
	private static final long serialVersionUID = 49823490L;
	private MoveValidator validator;
	private SimpleMoveGenerator generator;
	private AttackDiagramBuilder builder;
	
	private Board board;
	
	private boolean isOver = false;
	private int winner = 0;
	
	/**
	 * 
	 */
	public boolean isOver() {
		return isOver;
	}
	
	/**
	 * 
	 */
	public int getWinner() {
		return winner;
	}
	
	public MateValidator() {
		validator = new AdvancedMoveValidator();
		builder = new AdvancedAttackDiagramBuilder();
		generator = new SimpleMoveGenerator();
	}
	
	/*
		checking if there are enough matherial to win. 
	 */
	private boolean enoughMaterial() {
		boolean hasEnough = false;
		int amLightWhite = 0; // ������ ����� � �����
		int amLightBlack = 0; // ������ ����� � ������
		
		for (int i=0;i<Board.SIZE;++i) {
			int cur = board.getPiece(i);
			if (cur == Piece.WR || cur == Piece.WQ || cur == Piece.WP) {
				hasEnough = true;
				break;
			}
			if (cur == Piece.BR || cur == Piece.BQ || cur == Piece.BP) {
				hasEnough = true;
				break;
			}
			if (cur == Piece.WB || cur == Piece.WN)
				amLightWhite++;
			if (cur == Piece.BB || cur == Piece.BN)
				amLightBlack++;			
		}
		
		if (amLightWhite >= 2 || amLightBlack >= 2)
			hasEnough = true;
		return hasEnough;
	}
	
	/**
	 * Processes a game.
	 * @param game
	 */
	public void process(Game game) {
		this.board = game.getBoard();
		
		AttackDiagram diagram = builder.buildAttackDiagram(board);
		LinkedList<Move> moves = generator.generateMoves(board);
		
		boolean toMove = board.isWhiteToMove();
		boolean isCheck = toMove && !diagram.isCheckToWhite() || !toMove && diagram.isCheckToBlack();
		boolean hasMoves = false;
		for (Move m : moves) {
			if (validator.isValid(board, m))
				hasMoves = true;
		}
		
		// mate
		if (isCheck && !hasMoves) {			
			if (toMove)
				winner = StandaloneLuzhin.BLACK;
			else
				winner = StandaloneLuzhin.WHITE;
			isOver = true;
			return;
		}
		
		// stalemate
		if (!isCheck && !hasMoves) {
			winner = StandaloneLuzhin.NONE;
			isOver = true;
			return;
		}
		
		// not enough material
		if (!enoughMaterial()) {
			winner = StandaloneLuzhin.NONE;
			isOver = true;
			return;			
		}
		
		// game goes on
		isOver = false;
		winner = StandaloneLuzhin.NONE;
	}		
}
